/**
 *
 * <p>Title: HDTimer.java</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2004 Sun Microsystems, Inc.</p>
 * <p>Company: Sun Microsystems, Inc</p>
 * @author Jeff Kesselman
 * @version 1.0
 */
package com.worldwizards;
 
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.filechooser.FileFilter;

import com.hero.Hero;
import com.hero.HeroDesigner;
import com.hero.Prefab;
import com.hero.Template;
import com.hero.event.HeroDesignerEventListenerI;
import com.hero.ui.MainContentPanel;

/**
 *
 * <p>Title: HDTimerPlugin.java</p>
 * <p>Description: The framework that plugs the combat timer into HeroDesigner </p>
 * <p>Copyright: Copyright (c) Jeffrey P. Kesselman</p>
 * @author Jeff Kesselman
 * @version 1.0
 */
public class HDTimerPlugin {

    HeroDesigner hdesigner = HeroDesigner.getInstance();
    JLabel roundLabel, segmentLabel;
    JList characterActionList;
    JTable charactersParticipating;
    JFileChooser loadDialog;
    HeroSelector heroSelector;
    private Map<String, HeroPlaytimeRecord> loadedPTRs =
            new HashMap<String, HeroPlaytimeRecord>();
    private HeroCombatTimer timer = new HeroCombatTimer();

    @SuppressWarnings({"serial", "static-access"})
    public HDTimerPlugin() {

        final MainContentPanel mainPane = hdesigner.getMainPanel();
        final JPanel timerPanel = new JPanel();
        timerPanel.setName("CombatTimer");
        mainPane.addTab("CombatTimer", timerPanel);
        loadDialog = new JFileChooser(System.getProperty("user.dir"));
        loadDialog.setFileFilter(new FileFilter() {

            public boolean accept(File file) {
                return (file.isDirectory() || file.getName().endsWith(".hdc"));
            }

            @Override
            public String getDescription() {
                return "Hero Designer Character";
            }
        });
        loadDialog.setMultiSelectionEnabled(true);
        //loadDialog.setDirectory(System.getProperty("user.dir"));

        timerPanel.setLayout(new GridLayout(1, 2));
        JPanel topPane = new JPanel();
        topPane.setLayout(new GridLayout(1, 0));
        roundLabel = new JLabel("ROUND: 0");
        segmentLabel = new JLabel("SEGMENT: 0");
        topPane.add(roundLabel);
        topPane.add(segmentLabel);
        JPanel segmentPane = new JPanel();
        segmentPane.setLayout(new BorderLayout());
        segmentPane.add(topPane, BorderLayout.NORTH);
        characterActionList = new JList(new DefaultListModel());
        characterActionList.setCellRenderer(new ListCellRenderer() {

            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                HeroPlaytimeRecord rec = (HeroPlaytimeRecord) value;
                JLabel label = new JLabel(rec.name);
                if (rec.isStunned()) {
                    label.setForeground(Color.GRAY);
                } else if (isSelected) {
                    label.setForeground(Color.GREEN);
                } else {
                    label.setForeground(Color.BLACK);
                }
                return label;
            }
        });
        segmentPane.add(new JScrollPane(characterActionList), BorderLayout.CENTER);
        JPanel controlPanel = new JPanel();
        controlPanel.setLayout(new BorderLayout());
        JPanel combattantListPanel = new JPanel();
        combattantListPanel.setLayout(new BorderLayout());
        combattantListPanel.add(new JLabel("Characters in battle:"), BorderLayout.NORTH);
        JPanel timerCtrlPanel = new JPanel();
        timerCtrlPanel.setLayout(new GridLayout());
        JButton advanceCharacter = new JButton("Next Character");
        advanceCharacter.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                nextCharacter();

            }
        });
        JButton takeRecovery = new JButton("Take Recovery");
        takeRecovery.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                takeRecovery();

            }
        });
        JButton resetTimer = new JButton("Reset Timer");
        resetTimer.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                resetTimer();

            }
        });

        timerCtrlPanel.add(advanceCharacter);
        timerCtrlPanel.add(takeRecovery);
        timerCtrlPanel.add(resetTimer);
        segmentPane.add(timerCtrlPanel, BorderLayout.SOUTH);
        final PlaytimeRecTableModel tabelModel = new PlaytimeRecTableModel();
        tabelModel.addTableModelListener(new TableModelListener() {

            public void tableChanged(TableModelEvent e) {
                if (e.getType() != TableModelEvent.UPDATE) {
                    timer.reportSegmentActors();
                } else {
                    for (int i = e.getFirstRow(); i <= e.getLastRow(); i++) {
                        timer.updateCharacterState(tabelModel.getHeroPlaytimeRecord(i));
                    }
                }
            }
        });
        charactersParticipating = new JTable(tabelModel);
        charactersParticipating.setDefaultRenderer(Object.class, new PlaytimeRecTableRenderer());
        charactersParticipating.setDefaultEditor(HeroPlaytimeRecord.class,
                new PlaytimeRecCellEditor());
        charactersParticipating.setCellSelectionEnabled(true);
        charactersParticipating.setDefaultEditor(Object.class, null);
        charactersParticipating.setDefaultEditor(String.class, null);
        charactersParticipating.setDefaultEditor(Integer.class, new DefaultCellEditor(new JTextField()) {

            public Component getTableCellEditorComponent(JTable table,
                    Object value,
                    boolean isSelected,
                    int row,
                    int column) {

                if (column == 0) { //click on character name
                    return null;
                } else { // click on value
                    JTextField text = (JTextField) super.getTableCellEditorComponent(
                            table, value, isSelected, row, column);
                    text.selectAll();
                    return text;
                }
            }
        });

        combattantListPanel.add(new JScrollPane(charactersParticipating), BorderLayout.CENTER);
        heroSelector = new HeroSelector(hdesigner.getAppFrame());
        heroSelector.addListener(new HeroSelectorListener() {

            public void heroAdded(HeroPlaytimeRecord rec) {
                addHero(rec);

            }

            public void heroRemoved(HeroPlaytimeRecord rec) {
                removeHero(rec);

            }
        });
        JButton selectorButton = new JButton("Show Hero Selector");
        selectorButton.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                heroSelector.showSelector(hdesigner.getOpenHeroes(),
                        timer.getCharacterSet());
            }
        });
        combattantListPanel.add(selectorButton, BorderLayout.SOUTH);
        controlPanel.add(combattantListPanel, BorderLayout.CENTER);
        timerPanel.add(controlPanel);
        timerPanel.add(segmentPane);
        // set up combat timer menus        
        JMenuBar menuBar = hdesigner.getMainMenuBar();
        JMenu ctimerMenu = new JMenu("CombatTimer");
        //menuBar.add(ctimerMenu);        
        //menuBar.revalidate();
        timer.addListener(new HeroCombatTimerListener() {

            public void actingThisSegment(List<HeroPlaytimeRecord> actingThisSegment) {
                DefaultListModel mdl = (DefaultListModel) characterActionList.getModel();
                mdl.clear();
                for (HeroPlaytimeRecord rec : actingThisSegment) {
                    mdl.addElement(rec);
                }
            }

            public void endOfRound(int round) {
            // TODO Auto-generated method stub

            }

            public void playerAddedToCombat(HeroPlaytimeRecord prec) {
            // TODO Auto-generated method stub

            }

            public void playerRemovedFromCombat(HeroPlaytimeRecord prec) {
            // TODO Auto-generated method stub

            }

            public void segmentChange(int round, int segment) {
                roundLabel.setText("Round: " + round);
                segmentLabel.setText("Segment: " + segment);
                roundLabel.repaint();
                segmentLabel.repaint();

            }

            public void actingCharacterIndex(int actingIndex) {
                setActingCharacter(actingIndex);

            }

            public void characterRecordStateChange(HeroPlaytimeRecord rec) {
            // TODO Auto-generated method stub

            }
        });
        hdesigner.addListener(new HeroDesignerEventListenerI() {

            public void applicationShutdown() {
            // TODO Auto-generated method stub

            }

            public void characterLoaded(Hero arg0, boolean arg1) {
            // TODO Auto-generated method stub

            }

            public void displayReset() {
                mainPane.addTab("Combat Timer", timerPanel);

            }

            public void prefabLoaded(Prefab arg0) {
            // TODO Auto-generated method stub

            }

            public void preferencesChanged() {
            // TODO Auto-generated method stub

            }

            public void tabChanged() {
            // TODO Auto-generated method stub

            }

            public void templateChanged(Template arg0) {
            // TODO Auto-generated method stub

            }
        });
        timer.reset();
    }

    protected void takeRecovery() {
        timer.takeRecovery();

    }

    protected void resetTimer() {
        timer.reset();

    }

    /**
     * 
     */
    protected void nextCharacter() {
        timer.advanceActingCharacter();

    }

    /**
     * @param actingIndex
     */
    protected void setActingCharacter(int actingIndex) {
        characterActionList.setSelectedIndex(actingIndex);

    }

    /**
     * @param rec
     */
    protected void removeHero(HeroPlaytimeRecord rec) {
        PlaytimeRecTableModel model = (PlaytimeRecTableModel) charactersParticipating.getModel();
        loadedPTRs.remove(rec.name);
        timer.removeCharacterFromCombat(rec);
        model.removePlaytimeRecord(rec);

    }

    /**
     * @param rec
     */
    protected void addHero(HeroPlaytimeRecord rec) {
        final PlaytimeRecTableModel model = (PlaytimeRecTableModel) charactersParticipating.getModel();
        loadedPTRs.put(rec.name, rec);
        timer.addCharacterToCombat(rec);
        model.addPlaytimeRecord(rec);
        rec.addListener(new HeroPlaytimeRecordListener() {

            public void recordChanged(HeroPlaytimeRecord rec) {
                model.fireRecordUpdated(rec);

            }
        });
    }

    /**
     * 
     */
    protected void rewindSegment() {
        timer.previousSegment();

    }

    /**
     * 
     */
    protected void advanceSegment() {
        timer.advanceSegment();
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.println("Hellow World");
        new HDTimerPlugin();


    }
}
